package fr.obsmip.sedoo.client.activity;

import static fr.obsmip.sedoo.client.event.ActionEventConstant.MARKER_LOADING_EVENT;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.maps.client.LoadApi;
import com.google.gwt.maps.client.LoadApi.LoadLibrary;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AcceptsOneWidget;

import fr.obsmip.sedoo.client.ClientFactory;
import fr.obsmip.sedoo.client.ShortcutFactory;
import fr.obsmip.sedoo.client.event.ActionEventConstant;
import fr.obsmip.sedoo.client.message.Message;
import fr.obsmip.sedoo.client.misc.ClientObservatoryList;
import fr.obsmip.sedoo.client.place.DatasetEntryDisplayingPlace;
import fr.obsmip.sedoo.client.place.ExperimentalSiteEntryDisplayingPlace;
import fr.obsmip.sedoo.client.place.GeoSummaryPlace;
import fr.obsmip.sedoo.client.place.ObservatoryEntryDisplayingPlace;
import fr.obsmip.sedoo.client.service.GeoSummaryService;
import fr.obsmip.sedoo.client.service.GeoSummaryServiceAsync;
import fr.obsmip.sedoo.client.service.MetadataService;
import fr.obsmip.sedoo.client.service.MetadataServiceAsync;
import fr.obsmip.sedoo.client.ui.GeoSummaryView;
import fr.obsmip.sedoo.client.ui.GeoSummaryView.Presenter;
import fr.obsmip.sedoo.client.ui.misc.Shortcut;
import fr.obsmip.sedoo.shared.api.IsObservatory;
import fr.obsmip.sedoo.shared.domain.AbstractGeoSummaryDTO;
import fr.sedoo.commons.client.callback.LoadCallBack;
import fr.sedoo.commons.client.event.ActionStartEvent;
import fr.sedoo.commons.client.message.CommonMessages;
import fr.sedoo.commons.client.service.DefaultAbstractCallBack;
import fr.sedoo.commons.client.widget.DialogBoxTools;

public class GeoSummaryActivity extends RBVAbstractActivity implements Presenter, LoadCallBack<ArrayList<IsObservatory>> {

	private final GeoSummaryServiceAsync GEOSUMMARY_SERVICE = GWT.create(GeoSummaryService.class);
	private static final MetadataServiceAsync METADATA_SERVICE = GWT.create(MetadataService.class);
	private GeoSummaryView geoSummaryView;
	private Set<String> observatoryStack = new HashSet<String>();

	public GeoSummaryActivity(GeoSummaryPlace place, ClientFactory clientFactory) {
		super(clientFactory);
	}

	@Override
	public void start(AcceptsOneWidget containerWidget, EventBus eventBus) 
	{
		loadMapApi(containerWidget, eventBus);
	}

	private void postLoad(AcceptsOneWidget containerWidget, EventBus eventBus)
	{
		geoSummaryView = clientFactory.getGeoSummaryView();
		geoSummaryView.setPresenter(this);
		containerWidget.setWidget(geoSummaryView.asWidget());
		broadcastActivityTitle(Message.INSTANCE.systemViewHeader());
		List<Shortcut> shortcuts = new ArrayList<Shortcut>();
		shortcuts.add(ShortcutFactory.getWelcomeShortcut());
		shortcuts.add(ShortcutFactory.getGeoSummaryShortcut());
		clientFactory.getBreadCrumb().refresh(shortcuts);

		final ActionStartEvent e = new ActionStartEvent(CommonMessages.INSTANCE.loading(), ActionEventConstant.OBSERVATORIES_LOADING_EVENT, true);
		clientFactory.getEventBus().fireEvent(e);

		ClientObservatoryList.getObservatories(this);

		broadcastActivityTitle(Message.INSTANCE.geoSummaryViewHeader());
	}

	private void loadMapApi(final AcceptsOneWidget containerWidget, final EventBus eventBus) {
		boolean sensor = false;

		// load all the libs for use in the maps
		ArrayList<LoadLibrary> loadLibraries = new ArrayList<LoadApi.LoadLibrary>();
		loadLibraries.add(LoadLibrary.GEOMETRY);
		loadLibraries.add(LoadLibrary.VISUALIZATION);

		Runnable onLoad = new Runnable() {
			@Override
			public void run() {
				postLoad(containerWidget, eventBus);
			}
		};

		LoadApi.go(onLoad, loadLibraries, sensor);
	}

	@Override
	public void loadGeoSummaries(final String observatoryName) 
	{
		observatoryStack.add(observatoryName);
		loadNextGeoSummaries();		
	}

	@Override
	public void loadAllGeoSummaries(final List<String> observatoryNames) 
	{
		observatoryStack.addAll(observatoryNames);
		loadNextGeoSummaries();		
	}



	public void loadNextGeoSummaries() 
	{
		Iterator<String> iterator = observatoryStack.iterator();
		final String observatoryName = iterator.next();
		final ActionStartEvent e = new ActionStartEvent(Message.INSTANCE.geoSummaryViewLoadingObsvervatory()+ " "+observatoryName, MARKER_LOADING_EVENT, true);
		clientFactory.getEventBus().fireEvent(e);
		GEOSUMMARY_SERVICE.getGeoSummaries(observatoryName, clientFactory.getDisplayLanguages(), new AsyncCallback<ArrayList<? extends AbstractGeoSummaryDTO>>() {

			@Override
			public void onSuccess(ArrayList<? extends AbstractGeoSummaryDTO> result) 
			{
				clientFactory.getEventBus().fireEvent(e.getEndingEvent());
				geoSummaryView.displayGeoSummaries(result, observatoryName);
				observatoryStack.remove(observatoryName);
				if (observatoryStack.isEmpty() == false)
				{
					loadNextGeoSummaries();
				}
			}

			@Override
			public void onFailure(Throwable caught) {
				clientFactory.getEventBus().fireEvent(e.getEndingEvent());
				DialogBoxTools.modalAlert(CommonMessages.INSTANCE.error(), CommonMessages.INSTANCE.anErrorHasOccurred() + " " + caught.getMessage());
			}
		});

	}

	@Override
	public void displayDataset(String uuid) {
		DatasetEntryDisplayingPlace place = new DatasetEntryDisplayingPlace();
		place.setUuid(uuid);
		clientFactory.getPlaceController().goTo(place);
	}

	@Override
	public void displayObservatory(String observatoryName) {
		//clientFactory.getEventBus().fireEvent(new ObservatoryNavigationEvent(observatoryName));
	}

	@Override
	public void displayExperimentalSite(String uuid) 
	{
		ExperimentalSiteEntryDisplayingPlace place = new ExperimentalSiteEntryDisplayingPlace();
		place.setUuid(uuid);
		clientFactory.getPlaceController().goTo(place);

	}

	@Override
	public void postLoadProcess(ArrayList<IsObservatory> result) {
		List<String> observatoryNames = new ArrayList<String>();
		if (result != null)
		{
			Iterator<IsObservatory> iterator = result.iterator();
			while (iterator.hasNext()) 
			{
				IsObservatory aux = iterator.next();
				observatoryNames.add(aux.getName());
			}
		}
		geoSummaryView.setObservatoryNames(observatoryNames);
		geoSummaryView.ensureVisible();
	}

	@Override
	public void displayExperimentalSiteFromDataset(String uuid) {

		ActionStartEvent startEvent = new ActionStartEvent(CommonMessages.INSTANCE.loading(), ActionEventConstant.EXPERIMENTAL_SITE_LOADING_EVENT, true);
		clientFactory.getEventBus().fireEvent(startEvent);
		METADATA_SERVICE.getExperimentalSiteUuidByDatasetUuid(uuid, new DefaultAbstractCallBack<String>(startEvent, clientFactory.getEventBus()) 
				{
			@Override
			public void onSuccess(String uuid) {
				super.onSuccess(uuid);
				ExperimentalSiteEntryDisplayingPlace place = new ExperimentalSiteEntryDisplayingPlace();
				place.setUuid(uuid);
				clientFactory.getPlaceController().goTo(place);
			}
				});
	}

	
	@Override
	public void displayObservatoryFromDataset(String uuid) {

		ActionStartEvent startEvent = new ActionStartEvent(CommonMessages.INSTANCE.loading(), ActionEventConstant.OBSERVATORIES_LOADING_EVENT, true);
		clientFactory.getEventBus().fireEvent(startEvent);
		METADATA_SERVICE.getObservatoryUuidByDatasetUuid(uuid, new DefaultAbstractCallBack<String>(startEvent, clientFactory.getEventBus()) 
				{
			@Override
			public void onSuccess(String uuid) {
				super.onSuccess(uuid);
				ObservatoryEntryDisplayingPlace place = new ObservatoryEntryDisplayingPlace();
				place.setUuid(uuid);
				clientFactory.getPlaceController().goTo(place);
			}
				});
	}

	@Override
	public void displayObservatoryFromExperimentalSite(String uuid) {
		ActionStartEvent startEvent = new ActionStartEvent(CommonMessages.INSTANCE.loading(), ActionEventConstant.OBSERVATORIES_LOADING_EVENT, true);
		clientFactory.getEventBus().fireEvent(startEvent);
		METADATA_SERVICE.getObservatoryUuidByExperimentalSiteUuid(uuid, new DefaultAbstractCallBack<String>(startEvent, clientFactory.getEventBus()) 
				{
			@Override
			public void onSuccess(String uuid) {
				super.onSuccess(uuid);
				ObservatoryEntryDisplayingPlace place = new ObservatoryEntryDisplayingPlace();
				place.setUuid(uuid);
				clientFactory.getPlaceController().goTo(place);
			}
				});
		
	}

}
